package com.hlkj.pay.service.home.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.hlkj.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.hlkj.pay.dto.home.*;
import com.hlkj.pay.infrastructure.mapper.merchant.MerchantInfoMapper;
import com.hlkj.pay.infrastructure.mapper.order.HomeStatisticsMapper;
import com.hlkj.pay.infrastructure.mapper.order.OrderStatisticsMapper;
import com.hlkj.pay.infrastructure.model.merchant.MerchantInfoDO;
import com.hlkj.pay.infrastructure.model.order.OrderStatisticsDO;
import com.hlkj.pay.service.CommonSnFilterService;
import com.hlkj.pay.service.home.IWorkbenchStatisticsService;
import com.hlkj.pay.util.DateUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@RequiredArgsConstructor
public class WorkbenchStatisticsServiceImpl extends CommonSnFilterService implements IWorkbenchStatisticsService {

    private final HomeStatisticsMapper homeStatisticsMapper;

    private final MerchantInfoMapper merchantInfoMapper;

    private final OrderStatisticsMapper orderStatisticsMapper;

    @Override
    public HomePageStatisticsDto statisticsOrders(HomePageCharsStatisticsQueryDto homePageCharsStatisticsQueryDto) {
        filterSn(homePageCharsStatisticsQueryDto);

        return homeStatisticsMapper.statisticsOrders(homePageCharsStatisticsQueryDto);
    }

    @Override
    public Integer statisticsMechants(HomePageCharsStatisticsQueryDto homePageCharsStatisticsQueryDto) {
        filterSn(homePageCharsStatisticsQueryDto);
        LambdaQueryWrapperX<MerchantInfoDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(MerchantInfoDO::getSn, homePageCharsStatisticsQueryDto.getSn());
        queryWrapper.inIfPresent(MerchantInfoDO::getSn, homePageCharsStatisticsQueryDto.getSnList());
        queryWrapper.eqIfPresent(MerchantInfoDO::getSnType, homePageCharsStatisticsQueryDto.getSnType());
        queryWrapper.geIfPresent(MerchantInfoDO::getCreateTime, homePageCharsStatisticsQueryDto.getStartQueryTime());
        queryWrapper.leIfPresent(MerchantInfoDO::getCreateTime, homePageCharsStatisticsQueryDto.getEndQueryTime());
        return merchantInfoMapper.selectCount(queryWrapper).intValue();
    }

    @Override
    public BigDecimal statisticsRecharge(HomePageCharsStatisticsQueryDto homePageCharsStatisticsQueryDto) {
        filterSn(homePageCharsStatisticsQueryDto);
        BigDecimal val = homeStatisticsMapper.statisticsRecharge(homePageCharsStatisticsQueryDto);
        return val != null ? val : new BigDecimal(0);
    }

    @Override
    public Map<String, HomePageCharsStatisticsDto> daysStatistics(HomePageCharsStatisticsQueryDto homePageCharsStatisticsQueryDto) {
        filterSn(homePageCharsStatisticsQueryDto);
        List<HomePageCharsStatisticsDto> homePageCharsStatisticsDtos = homeStatisticsMapper.daysStatistics(homePageCharsStatisticsQueryDto);
        String startTime = DateUtils.dateToString(homePageCharsStatisticsQueryDto.getStartQueryTime(), DatePattern.NORM_DATE_PATTERN);
        String endTime = DateUtils.dateToString(homePageCharsStatisticsQueryDto.getEndQueryTime(), DatePattern.NORM_DATE_PATTERN);
        List<String> dateList = createDates(startTime, endTime, false);
        Map<String, HomePageCharsStatisticsDto> map = new LinkedHashMap<>();
        dateList.forEach(date -> {
            map.put(date, homePageCharsStatisticsDtos.stream().filter(obj -> date.equals(obj.getSTime())).findFirst().orElse(new HomePageCharsStatisticsDto()));
        });
        return map;
    }

    @Override
    public Map<String, HomePageCharsStatisticsDto> monthStatistics(HomePageCharsStatisticsQueryDto homePageCharsStatisticsQueryDto) {
        filterSn(homePageCharsStatisticsQueryDto);
        List<HomePageCharsStatisticsDto> homePageCharsStatisticsDtos = homeStatisticsMapper.monthStatistics(homePageCharsStatisticsQueryDto);
        String startTime = DateUtils.dateToString(homePageCharsStatisticsQueryDto.getStartQueryTime(), DatePattern.NORM_DATE_PATTERN);
        String endTime = DateUtils.dateToString(homePageCharsStatisticsQueryDto.getEndQueryTime(), DatePattern.NORM_DATE_PATTERN);
        List<String> dateList = createDates(startTime, endTime, true);
        Map<String, HomePageCharsStatisticsDto> map = new LinkedHashMap<>();
        dateList.forEach(date -> {
            map.put(date, homePageCharsStatisticsDtos.stream().filter(obj -> date.equals(obj.getSTime())).findFirst().orElse(new HomePageCharsStatisticsDto()));
        });
        return map;
    }

    @Override
    public List<HomePageCharsStatisticsDto> merchantDayTop(HomePageCharsStatisticsQueryDto homePageCharsStatisticsQueryDto) {
        filterSn(homePageCharsStatisticsQueryDto);
        return homeStatisticsMapper.merchantDayTop(homePageCharsStatisticsQueryDto);
    }

    @Override
    public List<HomePageCharsStatisticsDto> payTypeStatistics(HomePageCharsStatisticsQueryDto homePageCharsStatisticsQueryDto) {
        filterSn(homePageCharsStatisticsQueryDto);
        return homeStatisticsMapper.payTypeStatistics(homePageCharsStatisticsQueryDto);
    }

    @Override
    public List<HomePageOrderSucessRateDto> statisticsSuccessRate(HomePageCharsStatisticsQueryDto homePageCharsStatisticsQueryDto) {
        filterSn(homePageCharsStatisticsQueryDto);
        String startTime = DateUtils.dateToString(homePageCharsStatisticsQueryDto.getStartQueryTime(), DatePattern.NORM_DATE_PATTERN);
        String endTime = DateUtils.dateToString(homePageCharsStatisticsQueryDto.getEndQueryTime(), DatePattern.NORM_DATE_PATTERN);
        List<String> dateList = createDates(startTime, endTime, false);
        List<HomePageOrderSucessRateDto> homePageOrderSucessRateDtos = homeStatisticsMapper.statisticsSuccessRate(homePageCharsStatisticsQueryDto);
        List<HomePageOrderSucessRateDto> ret = new ArrayList<>();
        dateList.forEach(date -> {
            HomePageOrderSucessRateDto tmp = homePageOrderSucessRateDtos.stream().filter(obj -> date.equals(obj.getSTime())).findFirst().orElse(null);
            if (tmp == null) {
                HomePageOrderSucessRateDto tt = new HomePageOrderSucessRateDto();
                tt.setSTime(date);
                ret.add(tt);
            } else ret.add(tmp);
        });
        return ret;
    }

    @Override
    public HomeStatisticsDto dataQuery(HomePageCharsStatisticsQueryDto homePageCharsStatisticsQueryDto) {
        filterSn(homePageCharsStatisticsQueryDto);
        OrderStatisticsDO orderStatisticsDO = homeStatisticsMapper.statisticsQuery(homePageCharsStatisticsQueryDto);
        if (orderStatisticsDO == null) orderStatisticsDO = new OrderStatisticsDO();
        HomeStatisticsDto homeStatisticsDto = new HomeStatisticsDto();
        homeStatisticsDto.setDayOrderAmount(orderStatisticsDO.getPayOrderAmount());
        homeStatisticsDto.setChargeAmount(orderStatisticsDO.getChargeAmount());
        homeStatisticsDto.setDayOrderCount(orderStatisticsDO.getPayOrderCount());
        homeStatisticsDto.setRefundAmount(orderStatisticsDO.getRefundAmount());
        homeStatisticsDto.setFeeAmount(orderStatisticsDO.getFeeAmount());
        homeStatisticsDto.setChannelFeeAmount(orderStatisticsDO.getChannelFeeAmount());
        homeStatisticsDto.setOrderSuccessRate(calRate(orderStatisticsDO.getPayOrderCount(), orderStatisticsDO.getSubmitOrderCount()));
        homeStatisticsDto.setOrderRefundRate(calRate(orderStatisticsDO.getRefundCount(), orderStatisticsDO.getSubmitOrderCount()));

//        homePageCharsStatisticsQueryDto.setRelationId(PayEnums.PAY_TYPE.WECHAT.getCode());
//        OrderStatisticsDO wxStatistics = homeStatisticsMapper.statisticsQuery(homePageCharsStatisticsQueryDto);
        homeStatisticsDto.setWxComplainRate(calRate(orderStatisticsDO.getComplainCount(), orderStatisticsDO.getPayOrderCount()));

        return homeStatisticsDto;
    }

    @Override
    public List<HomePageCharsStatisticsDto> merchantDayStatistics(HomePageCharsStatisticsQueryDto homePageCharsStatisticsQueryDto) {
        filterSn(homePageCharsStatisticsQueryDto);
        List<HomePageCharsStatisticsDto> homePageCharsStatisticsDtos = homeStatisticsMapper.daysStatistics(homePageCharsStatisticsQueryDto);
        String startTime = DateUtils.dateToString(homePageCharsStatisticsQueryDto.getStartQueryTime(), DatePattern.NORM_DATE_PATTERN);
        String endTime = DateUtils.dateToString(homePageCharsStatisticsQueryDto.getEndQueryTime(), DatePattern.NORM_DATE_PATTERN);
        List<String> dateList = createDates(startTime, endTime, false, false);
        List<HomePageCharsStatisticsDto> ret = new ArrayList<>();
        dateList.forEach(date -> {
            HomePageCharsStatisticsDto homePageCharsStatisticsDto = homePageCharsStatisticsDtos.stream().filter(obj -> date.equals(obj.getSTime())).findFirst().orElse(null);
            if (homePageCharsStatisticsDto == null) {
                homePageCharsStatisticsDto = new HomePageCharsStatisticsDto();
                homePageCharsStatisticsDto.setSTime(date);
            }
            ret.add(homePageCharsStatisticsDto);
        });
        return ret;
    }

    private BigDecimal calRate(Integer val, Integer total1) {
        if (val != null && total1 != null && val > 0 && total1 > 0) {
            BigDecimal total = new BigDecimal(total1);
            BigDecimal part = new BigDecimal(val);

            return part.divide(total, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
        }
        return new BigDecimal(0);
    }

    private List<String> createDates(String startTime, String endTime, boolean isMonth) {
        return createDates(startTime, endTime, isMonth, true);
    }

    private List<String> createDates(String startTime, String endTime, boolean isMonth, boolean orderBy) {
        //type 1 月， 2 天
        List<String> dateList = new ArrayList<>();
        // 将字符串转换为日期
        var startDate = DateUtil.parse(startTime, DatePattern.NORM_DATE_PATTERN);
        var endDate = DateUtil.parse(endTime, DatePattern.NORM_DATE_PATTERN);
        // 循环生成月份
        if (orderBy) {
            while (!startDate.isAfter(endDate)) {
                if (isMonth) {
                    dateList.add(DateUtil.format(startDate, DatePattern.NORM_MONTH_PATTERN));
                    startDate = DateUtil.offsetMonth(startDate, 1);
                } else {
                    dateList.add(DateUtil.format(startDate, DatePattern.NORM_DATE_PATTERN));
                    startDate = DateUtil.offsetDay(startDate, 1);
                }
            }
        } else {
            while (!startDate.isAfter(endDate)) {
                if (isMonth) {
                    dateList.add(DateUtil.format(endDate, DatePattern.NORM_MONTH_PATTERN));
                    endDate = DateUtil.offsetMonth(endDate, -1);
                } else {
                    dateList.add(DateUtil.format(endDate, DatePattern.NORM_DATE_PATTERN));
                    endDate = DateUtil.offsetDay(endDate, -1);
                }
            }
        }
        return dateList;
    }
}
